#ifndef SKINDETECT_H
#define SKINDETECT_H

#include <cv.h>

namespace mlgesture{

class SkinDetector
{

public:
	enum {
		MORPHING_METHOD_NONE = 0,
		MORPHING_METHOD_ERODE = 1,
		MORPHING_METHOD_ERODE_ERODE = 2,
		MORPHING_METHOD_ERODE_DILATE = 3,
		MORPHING_METHOD_DILATE = 4,
		MORPHING_METHOD_DILATE_DILATE = 5,
		MORPHING_METHOD_DILATE_ERODE = 6
	};

	static const int GSD_HUE_LT;
	static const int GSD_HUE_UT;
	static const int GSD_INTENSITY_LT;
	static const int GSD_INTENSITY_UT;

	SkinDetector(int morphing_method = MORPHING_METHOD_NONE, int user_hue_lt = GSD_HUE_LT, int user_hue_ut = GSD_HUE_UT,
			   int user_value_lt = GSD_INTENSITY_LT, int user_value_ut = GSD_INTENSITY_UT);
	virtual ~SkinDetector();

	virtual void process(const cv::Mat &input_bgr_image, cv::Mat &output_hue_mask);
	void setAdapt(const bool adapt);
	int getUserHueLt() const;
	int getUserHueUp() const;
	int getUserValueLt() const;
	int getUserValueUt() const;

private:
	class Histogram
	{
	private:
		int histogramSize_;
		int userHueLt_;
		int userHueUt_;

	protected:
		int findCoverageIndex(double surface_to_cover, int default_value = 0);

	public:
		cv::Mat fHistogram;
		Histogram(const int user_hue_lt, const int user_hue_ut);
		virtual ~Histogram();

		void findCurveThresholds(int &x1, int &x2, double percent = 0.05);
		void mergeWith(Histogram &source, double weight);
	};

	int skinHueLowerBound_;
	int skinHueUpperBound_;
	int morphingMethod_;
	double histogramMergeFactor_;
	double huePercentCovered_;
	Histogram histogramHueMotion_;
	Histogram skinHueHistogram_;
	cv::Mat imgLastValueFrame_;
	cv::Mat imgMotionFrame_;
	cv::Mat imgFilteredFrame_;
	cv::Mat imgTemp_;
	cv::Mat imgHSVFrame_;
	std::vector<cv::Mat> imgHSVChannels_;
	bool adapt_;
	int userHueLt_;
	int userHueUt_;
	int userValueLt_;
	int userValueUt_;
};

}
#endif // SKINDETECT_H
